/*
 * Copyright (c) 2016. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.tsinghuabigdata.edu.ddmath.util;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.Display;

import com.tsinghuabigdata.edu.ddmath.constant.ErrTag;
import com.tsinghuabigdata.edu.ddmath.module.mylearn.XBookCropImageActivity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 图片操作
 * Created by yanshen on 2016/4/7.
 */
public class BitmapUtils {

    /**
     * bitmap转byte array
     *
     * @param bm
     * @return
     */
    public static byte[] bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    public static byte[] getFilData(String filepath) {

        File file = new File(filepath);
        if (!file.exists() || file.length() == 0)
            return null;


        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte buffer[] = new byte[(int) file.length()];
            int len = fis.read(buffer);
            fis.close();
            if (len == file.length())
                return buffer;
        } catch (Exception e) {
            AppLog.i(ErrTag.TAG_FILE, e.toString());
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                    AppLog.i(e.toString());
                }
            }
        }
        return null;
    }

    /**
     * 把Bitmap保存为文件
     *
     * @param filepath 指定文件名
     * @param bitmap   图片
     * @return 保存的路径
     */
    public static String saveImage(String filepath, Bitmap bitmap) {

        if (TextUtils.isEmpty(filepath))
            return null;
        if (!filepath.endsWith("/"))
            filepath += "/";

        File dir = new File(filepath);
        dir.mkdirs();

        String filename = filepath + System.currentTimeMillis() + ".png";

        File file = new File(filename);
        if (file.exists()) {
            file.delete();
        }

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            return filename;
        } catch (Exception e) {
            AppLog.i("", e);
        } finally {
            try {
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                AppLog.i("", e);
            }
        }
        return null;
    }

    /**
     * 保存图片到指定目录，并更新到系统相册
     *
     * @param context
     * @param bmp
     */
    public static boolean saveImageToGallery(Context context, Bitmap bmp, String dir, String fname) {
        // 首先保存图片
        File appDir = new File(Environment.getExternalStorageDirectory(), dir);
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        if (TextUtils.isEmpty(fname)) {
            fname = System.currentTimeMillis() + ".jpg";
        } else {
            fname += ".jpg";
        }
        File file = new File(appDir, fname);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            AppLog.i(ErrTag.TAG_FILE, e.toString());
            return false;
        } catch (Exception e) {
            AppLog.i(ErrTag.TAG_IO, e.toString());
            return false;
        }

        // 其次把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fname, null);
        } catch (FileNotFoundException e) {
            AppLog.d( e.toString() );
        }
        // 最后通知图库更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + appDir.getAbsolutePath())));

        return true;
    }

    /**
     * @param drawable drawable 转  Bitmap
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        // 取 drawable 的长宽
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();

        // 取 drawable 的颜色格式
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                : Bitmap.Config.RGB_565;
        // 建立对应 bitmap
        Bitmap bitmap = Bitmap.createBitmap(w, h, config);
        // 建立对应 bitmap 的画布
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        // 把 drawable 内容画到画布中
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * @param bitmap
     * @param roundPx 获取圆角图片
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Bitmap output = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, w, h);
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }

    /**
     *
     */

    public static Bitmap decodeBitmap( String imageFile,Display currentDisplay ){

        //屏幕大小
        //Display currentDisplay = getWindowManager().getDefaultDisplay();
        int dw = currentDisplay.getWidth();
        int dh = currentDisplay.getHeight();


        // 得到图片大小但是不加载图片
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imageFile, opts);

        //int heightRatio = (int) Math.ceil(opts.outHeight / (float) dh);
        //int widthRatio = (int) Math.ceil(opts.outWidth / (float) dw);

        if( opts.outHeight > 6000 || opts.outWidth > 6000 ){
            opts.inSampleSize = 4;
        }else if( opts.outHeight > 2000 || opts.outWidth > 2000 ){
            opts.inSampleSize = 2;
        }

        // 解析图片
        opts.inJustDecodeBounds = false;
        //opts.inSampleSize = widthRatio;
        //opts.inSampleSize = 1;
        opts.inPreferredConfig = Bitmap.Config.RGB_565;

        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeFile(imageFile, opts);
        } catch (OutOfMemoryError err) {
            AppLog.d( err.toString() );
        }
        return bmp;
    }

    /**
     * 根据目标区域，从图片上面剪切指定图片
     */
    public static final boolean cropRectImage( Rect dstRect, Bitmap bitmap, String cropimagepath, double image_rate, Context context ){

        //映射到实际图片的位置
        int x1 = (int)( dstRect.left*image_rate );
        int y1 = (int)( dstRect.top*image_rate );
        int width = (int)( dstRect.width()*image_rate );
        int height = (int)( dstRect.height()*image_rate );

        if (x1 < 0)
            x1 = 0;
        else if( x1 > bitmap.getWidth() ){
            x1 = bitmap.getWidth();
        }

        if (y1 < 0)
            y1 = 0;
        else if( y1 > bitmap.getHeight() ){
            y1 = bitmap.getHeight();
        }

        if( x1 + width > bitmap.getWidth() ){
            width = bitmap.getWidth() -x1;
        }
        if( y1 + height > bitmap.getHeight() ){
            height = bitmap.getHeight() -y1;
        }

        //剪切图
        Bitmap tmp = Bitmap.createBitmap(bitmap, x1, y1, width, height);
        return compressImage( cropimagepath, tmp, context );
    }

    /*
     * 压缩图片  对图片尺寸和大小进行处理
     */
    public static final boolean compressImage( String cropimagepath, Bitmap bitmap, Context mContext ) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中

        int fsize = baos.toByteArray().length / 1024;
        AppLog.d( "----compressImage fsize =" + fsize + ",,,max_size = " + XBookCropImageActivity.OLD_SIZE );

        int options;

        /*if( fsize > 3000){
            options = 20;
        }else if( fsize > 2048 ){
            options = 30;
        }else if( fsize > 1024) {        //>1M
            options = 40;
        }else if( fsize > 700) {        //>
            options = 50;
        }else */if( fsize > 500) {        //>
            options = 80;
        }else if( fsize > 300) {        //>
            options = 70;
        }else if( fsize > 200) {        //>
            options = 90;
        }else {
            options = 100;
        }

        int tc = 0;
        //用于上传显示的图片
        if( fsize > XBookCropImageActivity.OLD_SIZE ){
            while ( baos.toByteArray().length / 1024 > XBookCropImageActivity.OLD_SIZE) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();//重置baos即清空baos
                options -= 10;//每次都减少10
                if( options <= 80 ){
                    options = 80;
                    break;
                }
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
                tc++;
            }
        }
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream( cropimagepath );
            if( !bitmap.compress(Bitmap.CompressFormat.JPEG, options, fout) ){
                AppLog.d( "----compressImage save fail " );
                return false;
            }
        } catch (Exception e) {
            AlertManager.toast( mContext, "磁盘空间不足，无法保存图片。" );
            AppLog.d("compressImage eee = " + e.toString() );
        }finally {
            if(fout != null) {
                try {
                    fout.close();
                    fout.flush();
                } catch (IOException e) {
                    AppLog.d( e.toString() );
                }
            }
        }
        return true;
    }


    /**
     *
     */
    public static String getUrlQuality( String url, int quality, String accessToken ){
        try{
            if( url.endsWith(".jpg") ){
                url = url.replace(".jpg",",q"+quality+".jpg");
            }else if( url.endsWith(".jpeg") ){
                url = url.replace(".jpeg",",q"+quality+".jpeg");
            }
            //url += "?access_token=" + accessToken;
        }catch (Exception e){AppLog.i(ErrTag.TAG_ENCODE, e.toString());}
        return url;
    }

}
